Skip to content

fix(hcg-policy): cover wired POST /cartridge/:name/sse (Phase E §1.5)#165

Merged
hyperpolymath merged 1 commit into
mainfrom
hcg-phase-e/policy-sse-resync
May 28, 2026
Merged

fix(hcg-policy): cover wired POST /cartridge/:name/sse (Phase E §1.5)#165
hyperpolymath merged 1 commit into
mainfrom
hcg-phase-e/policy-sse-resync

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Summary

Re-verifies config/gateway-policy-boj-example.yaml against the live BojRest.Router for HCG tier-2 rollout (Phase E §1.5 prereq, standards#100). The wired POST /cartridge/:name/sse route — elixir/lib/boj_rest/router.ex line 130, called out in ADR-0013 §6 and the STATE entry 2026-05-18 ("boj-rest SSE: POST /cartridge/:name/sse on the same single Cowboy listener + trust-gated dispatch") — was absent from the example policy. Silent surface drift since contract v1.0; exactly the risk Phase A flagged.

  • Adds cartridge-sse-post rule (regex ^/cartridge/[A-Za-z0-9_.-]+/sse$, POST, authenticated) alongside cartridge-invoke-post. Same BojRest.Router.check_trust/3 gate, same per-cartridge auth.method requirement, streaming envelope around a single dispatch.
  • Updates the example-policy "Surface source" header to record the 2026-05-28 re-verification and point at the new rule.
  • Ticks the §1.5 surface-coverage checkbox on docs/integration/hcg-tier2-rollout-runbook.md with the re-verification date; flags live-policy promotion as the remaining work before §3.1.

The unrelated top-level /sse GET rule (declared-not-yet-wired, openapi.yaml only) is left in place — different path, different verb, different surface.

What this PR does NOT do

  • Does not close standards#100. Phase E still has: gateway smoke-test against this policy (§1.5 next box); live-policy promotion (config/gateway-policy-boj.yaml); §1.4 !OWNER: block; Phase D-4 baseline (bench/baseline.json _status still "scaffold-placeholder" upstream — gates the perf-regression CI alert); staging soak (§2.3); production rollout (§3); §6.4 Trustfile flip.
  • Does not change runtime behaviour (config-only).

Test plan

  • Policy YAML re-parses (python3 -c "import yaml; yaml.safe_load(open('config/gateway-policy-boj-example.yaml'))"); 27 → 28 routes; global_verbs still [GET, POST].
  • Both sse-get (top-level, declared-not-yet-wired) and cartridge-sse-post (per-cartridge, wired) appear as distinct rules under the parsed governance.routes list.
  • All seven routes wired in BojRest.Router (/.well-known/boj-node-pubkey, /health, /menu, /cartridges, /cartridge/:name, /cartridge/:name/invoke, /cartridge/:name/sse) now have a matching policy entry.
  • Future (separate session, Phase E §2.1): stand the gateway up against this policy, confirm POST /cartridge/:name/sse with X-Trust-Level: authenticated proxies through and with X-Trust-Level: untrusted returns 403. Out of scope for this PR; that flips the §1.5 smoke-test checkbox, not this one.

Refs hyperpolymath/standards#100
Refs hyperpolymath/standards#91

🤖 Generated with Claude Code


Generated by Claude Code

Re-verified config/gateway-policy-boj-example.yaml against the live
BojRest.Router for HCG tier-2 rollout. The wired POST /cartridge/:name/sse
route (router.ex line 130; ADR-0013 §6; STATE 2026-05-18) was absent from
the example policy — silent surface drift since contract v1.0. Adds
`cartridge-sse-post` alongside `cartridge-invoke-post` (same trust gate,
same per-cartridge auth.method requirement, streaming response envelope
around a single dispatch). Ticks the §1.5 surface-coverage box on the
rollout runbook with the re-verification date; flags the live-policy
promotion (config/gateway-policy-boj.yaml) and the smoke-test box as
the remaining §1.5 work.

No runtime behaviour change. Policy YAML re-parses cleanly (27 → 28
rules; global_verbs unchanged: GET, POST). `sse-get` (top-level,
declared-not-yet-wired) and `cartridge-sse-post` (per-cartridge, wired)
coexist as distinct rules — different path, different verb.

Refs hyperpolymath/standards#100
Refs hyperpolymath/standards#91

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 179 issues detected

Severity Count
🔴 Critical 17
🟠 High 123
🟡 Medium 39

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Stale AI session file -- delete",
    "type": "stale",
    "file": "GEMINI.md",
    "action": "delete",
    "rule_module": "root_hygiene",
    "severity": "medium"
  },
  {
    "reason": "Issue in abi-drift.yml",
    "type": "unknown",
    "file": "abi-drift.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in codeql.yml",
    "type": "unknown",
    "file": "codeql.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in container-publish.yml",
    "type": "unknown",
    "file": "container-publish.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dogfood-gate.yml",
    "type": "unknown",
    "file": "dogfood-gate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dogfood-gate.yml",
    "type": "unknown",
    "file": "dogfood-gate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dogfood-gate.yml",
    "type": "unknown",
    "file": "dogfood-gate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dogfood-gate.yml",
    "type": "unknown",
    "file": "dogfood-gate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dogfood-gate.yml",
    "type": "unknown",
    "file": "dogfood-gate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dogfood-gate.yml",
    "type": "unknown",
    "file": "dogfood-gate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath hyperpolymath marked this pull request as ready for review May 28, 2026 07:18
@hyperpolymath hyperpolymath enabled auto-merge (squash) May 28, 2026 07:18
@hyperpolymath hyperpolymath disabled auto-merge May 28, 2026 07:36
@hyperpolymath hyperpolymath merged commit ff9f2be into main May 28, 2026
22 of 23 checks passed
@hyperpolymath hyperpolymath deleted the hcg-phase-e/policy-sse-resync branch May 28, 2026 07:36
hyperpolymath added a commit that referenced this pull request Jun 8, 2026
…ards#91 / #100)

Refreshes docs/integration/hcg-tier2-rollout-runbook.md from v0.1
(draft, 2026-05-20, pre Phase-D) to v0.2 reflecting the current
state of the single-lane channel rooted at standards#91:

- §1.1 Phase D deliverables: tick D-1..D-3 + D-4 bootstrap with
  http-capability-gateway PR refs (#12 / #14 / #22 / #26 / #30) and
  the boj-server D-1 load-profile (#168) that joint-closed standards#99
  on 2026-06-01. The one remaining open item is the owner-driven
  perf-rebaseline workflow dispatch + `_status: scaffold-placeholder
  -> active` flip; called out explicitly rather than left as a stale
  unchecked checkbox.

- §1.4 BoJ-side prereqs: tick the three loopback-bind layers
  (#130 / #131 / #132), the Phase C TrustPolicy clause (#106), the
  NetworkPolicy (#173), and the SSE-route policy coverage (#165).
  The Trustfile `tier_2_gateway.status: PENDING` line stays
  intentionally unchecked - it's the §6.4 last-action target.

- §1.5 Gateway-side prereqs: tick the new
  `container/gateway-deploy.k9.ncl` from http-capability-gateway#38
  (2026-06-03), record what stays PLACEHOLDER until cerro-torre
  signing runs, and expand the smoke-test entry with the concrete
  allow/deny sequence boj-server#165 deferred.

- Header banner: replace the stale "Phase D has merged the scaffold
  only" Phase-D-dependency note with a current-state summary,
  bump version 0.1 -> 0.2, date 2026-05-20 -> 2026-06-08.

- CHANGELOG.md: Documentation entry under [Unreleased] summarising
  the refresh.

No code, infrastructure, or runtime behaviour changes. The runbook
is the operator-facing source of truth for what's gating the next
Phase E owner action; the drift it had was making "what's still
open" harder to read at a glance.

Refs hyperpolymath/standards#91
Refs hyperpolymath/standards#100

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request Jun 9, 2026
)

## Summary

Lands `config/gateway-policy-boj.yaml` — the **live** Verb Governance
Spec
the HCG tier-2 gateway loads via `POLICY_PATH` in staging (§2.1) and
production (§3.1) per the rollout runbook. The Phase A worked example
(`config/gateway-policy-boj-example.yaml`) is retained as the
documentation
artefact; the live file is now the operational one. Closes the
example→live
promotion item on the Phase E §1.5 checklist.

Single-lane HCG tier-2 channel (`standards#91`). Phase A (#96), B (#97),
C (#98), D (#99) are joint-closed; Phase E (`standards#100`) is the
active
phase, with multiple artefacts gating closure (§6.4 Trustfile flip is
the
last). This PR lands one tractable artefact; staging soak (§2),
production
traffic split (§3) and the §6.4 flip remain owner-driven.

## What this PR lands

- **`config/gateway-policy-boj.yaml`** — live policy file.
Content-identical
to `gateway-policy-boj-example.yaml` at promotion time. Header rewritten
  to reflect its live-file role (operational artefact, not pedagogical),
with `DEFAULT-DENY INVARIANT` reframed from "Phase A check" to
"permanent
invariant — must hold for every future gateway release". DSL v1
conformance
preserved; all 28 routes (`global_verbs: [GET, POST]`; per-route
`verbs`,
  `exposure`, `name`, `narrative`; `stealth_profile` on internal routes;
top-level `stealth: { enabled: true, status_code: 404 }`) carried
forward
  unchanged.
- **Runbook §1.5** — flips the trailing "still to be promoted from this
example before §3.1" note (on the existing `[x]` example-in-place line)
  to a discrete `[x]` item recording the live file's existence and the
divergence policy ("future BoJ-surface evolution lands in the live file;
  the example remains as the worked-example artefact").
- **Runbook §2.1 step 2** — switches staging `POLICY_PATH` from the
example
to the live file so staging exercises the same artefact that production
  will. Production §3.1 (which inherits §2.1's environment with the
  traffic-shift mechanism overlaid) needs no change.
- **Runbook header** — version 0.2 → 0.3; status line updated to
acknowledge
  the live-policy promotion.

## What this PR deliberately does NOT do

- **Close `standards#100`.** Per runbook §6.5 the joint-close happens
after
  the §6.4 Trustfile flip (`tier_2_gateway.status: PENDING → DEPLOYED`),
which itself follows the §3.3 100% production-soak window. Using `Refs`
  not `Closes` to match the established Phase E pattern (PRs #38, and
Phase D PRs #14, #22, #26, #30 — all `Refs`'d their phase issue and the
  owner joint-closed the issue once the final artefact landed). This
  deliberately diverges from the dispatch brief's literal "Closes
  hyperpolymath/standards#<phase-issue-number>" line in favour of the
canonical runbook §6.5 close-out discipline that the brief itself points
  to as the source of truth ("using the canonical sources"). The owner
  remains the sole closer of `standards#100`.
- **Touch the HCG deploy spec.** `container/gateway-deploy.k9.ncl` in
`hyperpolymath/http-capability-gateway` (PR #38) reads `POLICY_PATH` at
deploy time from the env, so the live-file cut-over is a runbook +
config
artefact change on the BoJ side, not a deploy-spec change on the gateway
  side. No companion PR on the gateway repo.
- **Diverge the live file from the example.** At promotion the two files
are content-identical. Future divergence is intentional and the live
file
  is authoritative; the example may be intentionally simpler.
- **Trigger any deploy.** No traffic shift, no staging cut-over, no §6.4
  flip happens at merge time. This is a static artefact landing.
- **Update the deploy spec's `POLICY_PATH` default.** The deploy spec
carries env-var declarations; the live-file path is operator-supplied at
  deploy time.

## Verification

- [x] DSL v1 conformance: `dsl_version: "1"`; `governance.global_verbs`
is
      `[GET, POST]`; every route has a non-empty `verbs`; `exposure ∈
      {public, authenticated, internal}`; `stealth.enabled` boolean,
      `stealth.status_code: 404` in 100..599.
- [x] All 28 example routes preserved unchanged in the live file (route
      count, `name`s, paths, verbs, exposures, narratives).
- [x] SPDX header `MPL-2.0` matches repo convention (config/, docs/).
- [x] Runbook §1.5 and §2.1 cross-references to
`gateway-policy-boj.yaml`
      and `gateway-policy-boj-example.yaml` resolve.
- [ ] Manual: `mix gateway.validate config/gateway-policy-boj.yaml`
      (gateway-side; can be run by the operator before §2.1 stand-up —
      see runbook §1.5 last open item, smoke-test).

## Channel position

```
standards#91 (parent, open)
├── #96 Phase A — closed (boj-server: contract + policy-authoring + example; gateway: -)
├── #97 Phase B — closed (gateway#10: mTLS primary path)
├── #98 Phase C — closed (gateway#11: strip; boj-server#106: TrustPolicy clause)
├── #99 Phase D — closed (boj-server#168 on 2026-06-01; gateway#12/#14/#22/#26/#30)
└── #100 Phase E — IN PROGRESS
     ├── E5 runbook draft — boj-server#128 (landed; rehearsal pending)
     ├── E1 loopback prereqs — boj-server#130/#131/#132/#165/#173 (landed)
     ├── E1 deploy spec — http-capability-gateway#38 (landed)
     ├── E1 live policy promotion — THIS PR (in review)
     ├── E1 .ctp signing — owner follow-up
     ├── E2 staging cut-over — owner follow-up
     ├── E3 telemetry verification — owner follow-up
     ├── E4 production rollout — owner follow-up
     └── §6.4 Trustfile flip + §6.5 joint-close — owner-only
```

Refs hyperpolymath/standards#91
Refs hyperpolymath/standards#100

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---
_Generated by [Claude
Code](https://claude.ai/code/session_012FiVM8R8FWBgBsUGpnXTZM)_

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request Jun 12, 2026
#210)

## Summary

Lands `scripts/hcg-policy-smoke.sh` — a checked-in smoke that exercises
the HCG tier-2 live Verb Governance Spec
(`config/gateway-policy-boj.yaml`) from outside the gateway. Replaces
the manual probe sequence the rollout runbook §1.5 last open item
formerly described as "out of band — operator pre-check".

Single-lane HCG tier-2 channel (`standards#91`). Phase A (#96), B (#97),
C (#98), D (#99) are joint-closed; Phase E (`standards#100`) is the
active phase. This PR lands one tractable artefact (§1.5 operator
pre-check now checked-in and reproducible); staging soak (§2),
production traffic split (§3), and the §6.4 Trustfile flip remain
owner-driven.

## What this PR lands

- **`scripts/hcg-policy-smoke.sh`** — POSIX-conformant bash + curl, no
  jq/yq dependency.
  - **Deny mode (default)**: sends one no-trust-header probe to every
    non-public route in the live policy (25 routes spanning the 19
    authenticated and 6 internal+stealth entries) and asserts a 4xx
    response. The 4xx assertion covers both bare 403 and stealth-profile
    codes regardless of the gateway's `:stealth_profiles` runtime
    config. Plus a default-deny verb canary (DELETE /cartridges, PUT
    /health, PATCH /cartridges) confirming `global_verbs: [GET, POST]`
    enforces the ADR-0004 verb-governance invariant for un-listed verbs.
    Gateway-internal — BoJ does **not** have to be reachable.
  - **`--with-backend` mode**: additionally probes the allow path with
    `X-Trust-Level: authenticated` (and `internal` for internal+stealth
    routes), asserting the response is NOT a gateway-origin 4xx (2xx /
    3xx / 5xx all pass — BoJ's own status is fine; only a gateway deny
    is a failure). Requires BoJ reachable at the gateway's `BACKEND_URL`
    and the script to run from a trusted-proxy IP so the trust header is
    not stripped by the gateway's `strip_untrusted_headers` plug.
  - Exits 0 on all-PASS, 1 on any FAIL (with per-probe summary), 64 on
    usage error.

- **Runbook §1.5** — last unchecked operator pre-check item flips from
  a free-form "stand the gateway up ... exercise one allow + one deny
  per route" sequence (which was deferred to boj-server#165's test plan
  and documented as out-of-band) to a single
  `scripts/hcg-policy-smoke.sh` invocation. The PASS/FAIL summary
  attaches to the cut-over ticket; a single FAIL is a stop-the-rollout
  condition with the three failure modes named (policy not enforcing,
  BoJ unreachable, non-trusted-proxy caller stripping the header).

- **Runbook header** — version 0.3 → 0.4; date 2026-06-09 → 2026-06-10;
  status line acknowledges the smoke script landing alongside the
  existing live policy promotion.

- **Runbook Appendix B** — new cross-reference entry for
  `scripts/hcg-policy-smoke.sh`.

## What this PR deliberately does NOT do

- **Close `standards#100`.** Per runbook §6.5 the joint-close happens
  after the §6.4 Trustfile flip (`tier_2_gateway.status: PENDING →
  DEPLOYED`), which itself follows the §3.3 100% production-soak
  window. Using `Refs` to match the Phase E PR convention established
  by #208 / #38 / #168 and documented in §6.5 ("Do not self-close
  standards#100; joint-close is owner-only per the single-lane channel
  discipline"). The owner remains the sole closer of `standards#100`.
- **Touch HCG.** This is a BoJ-side artefact: the script lives in
  `scripts/`, reads `config/gateway-policy-boj.yaml`, and probes the
  gateway over HTTP. No companion PR on the gateway repo required.
- **Run during CI deployment.** The script is checked in but only the
  operator's explicit invocation against a live gateway URL exercises
  it. CI does not stand up a gateway to run it (would require an
  external service); the script is intentionally operator-driven, with
  the PASS/FAIL summary attached to the cut-over ticket as the
  evidence-of-pre-check artefact.
- **Diverge the policy from the script's route matrix.** The script's
  route matrix mirrors the 25-route live policy. When the policy file
  evolves (new BoJ surface routes wired in), the script must be updated
  in lock-step — that is a benefit not a cost (the script doubles as a
  policy-completeness checklist), but it must be observed.

## Verification

- [x] `bash -n scripts/hcg-policy-smoke.sh` — syntax check passes.
- [x] `scripts/hcg-policy-smoke.sh` (no args) — exits 64 (usage error).
- [x] `scripts/hcg-policy-smoke.sh --help` — exits 64 with full help.
- [x] Against a synthetic always-403 mock on :18443 — `PASS=28 FAIL=0`,
      exits 0 (deny-only mode covers all 25 policy routes + 3 verb
      canaries).
- [x] Against a closed port (no gateway up) — every probe FAILs with
      `got=000 expected=deny`; exits 1 with the FAIL line summary.
- [x] SPDX header `MPL-2.0` matches repo convention (scripts/, docs/).
- [x] Runbook cross-references resolve (`§1.5`, Appendix B, sibling
      docs).

## Channel position

```
standards#91 (parent, open)
├── #96 Phase A — closed (boj-server: contract + policy-authoring + example; gateway: -)
├── #97 Phase B — closed (gateway#10: mTLS primary path)
├── #98 Phase C — closed (gateway#11: strip; boj-server#106: TrustPolicy clause)
├── #99 Phase D — closed (boj-server#168 on 2026-06-01; gateway#12/#14/#22/#26/#30)
└── #100 Phase E — IN PROGRESS
     ├── E5 runbook draft — boj-server#128 (landed; rehearsal pending)
     ├── E1 loopback prereqs — boj-server#130/#131/#132/#165/#173 (landed)
     ├── E1 deploy spec — http-capability-gateway#38 (landed)
     ├── E1 live policy promotion — boj-server#208 (landed)
     ├── §1.5 operator pre-check smoke — THIS PR (in review)
     ├── E1 .ctp signing — owner follow-up
     ├── E2 staging cut-over — owner follow-up
     ├── E3 telemetry verification — owner follow-up
     ├── E4 production rollout — owner follow-up
     └── §6.4 Trustfile flip + §6.5 joint-close — owner-only
```

Refs hyperpolymath/standards#91
Refs hyperpolymath/standards#100

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---
_Generated by [Claude
Code](https://claude.ai/code/session_01SE4pkWg8SEKsSWK9geD5r9)_

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request Jun 13, 2026
## Summary

Tightens `scripts/hcg-policy-smoke.sh` against three verb-governance
regression classes the original three canaries (DELETE/PUT/PATCH on
`/cartridges` and `/health`) don't catch. Single-lane HCG tier-2 channel
(`standards#91`); Phase E (`standards#100`) is the active phase.

## What this PR adds

Three new deny-mode verb-canary probes:

1. **`OPTIONS /cartridges`** — `global_verbs: [GET, POST]` bans OPTIONS,
but a CORS preflight auto-responder added later would silently bypass
policy. The canary fails closed against that regression class.

2. **`DELETE /cartridge/probe/invoke`** — exercises the regex route
`^/cartridge/[A-Za-z0-9_.-]+/invoke$` under a banned verb. The existing
exact-path canaries don't catch a regex-matcher regression where the
path is accepted under any verb instead of only the verb the rule lists.

3. **`GET /cartridges/ssg-mcp/webhook`** — the path is in the policy as
a documented public exception, but only for POST. The canary verifies
the `{path, verb}` pairing is enforced: GET on the same path must
default-deny because no rule covers it.

Runbook §1.5 description updated to enumerate the expanded canary set;
runbook version bump 0.4 → 0.5.

## What this PR deliberately does NOT do

- **Probe HEAD.** Curl with `-X HEAD` (vs `--head`) waits for a body the
server will not send, which interacts badly with the script's
`--max-time 10`. HEAD enforcement remains covered by the gateway's own
unit tests; the §1.5 operator pre-check focuses on probes that survive
curl's method quirks. The reasoning is captured inline in the script
comment so a future maintainer doesn't add it back as an oversight.

- **Extend the `--with-backend` allow-path matrix.** The authenticated
routes the script probes in allow mode are the ones actually wired in
`BojRest.Router`; the additional policy entries (`graphql`, `sse`,
`order`, `umoja/*`, etc.) are declared-not-yet-wired per contract §8 and
would 404 from BoJ, which the `allow_or_upstream` pattern misdiagnoses
as gateway-deny. They stay in the deny matrix until they are wired in
BoJ. The `ssg-mcp-webhook-post` route is not added to the
`--with-backend` allow probes for the same reason.

- **Auto-derive the probe matrix from the policy YAML.** The matrix
stays hand-maintained and the parity-with-policy property remains a
manual maintenance discipline. PR #210's commitment ("the script doubles
as a policy-completeness checklist") is preserved.

- **Close `standards#100`.** Per runbook §6.5 the joint-close happens
after the §6.4 Trustfile flip, which itself follows the §3.3 100%
production-soak window. Using `Refs` per the Phase E PR convention (#38,
#208, #210).

## Verification

- [x] `bash -n scripts/hcg-policy-smoke.sh` — syntax check passes.
- [x] Synthetic always-403 mock on `:18443` — `PASS=31 FAIL=0` (was 28);
the three new canaries report PASS; exit 0.
- [x] `--help` and bad-args exit codes unchanged (64).
- [x] SPDX header `MPL-2.0` unchanged.
- [x] Runbook cross-references resolve.

## Channel position

```
standards#91 (parent, open)
├── #96 Phase A — closed
├── #97 Phase B — closed
├── #98 Phase C — closed
├── #99 Phase D — closed (joint-closed via boj-server#168)
└── #100 Phase E — IN PROGRESS
     ├── E5 runbook draft — boj-server#128 (landed)
     ├── E1 loopback prereqs — boj-server#130/#131/#132/#165/#173 (landed)
     ├── E1 deploy spec — http-capability-gateway#38 (landed)
     ├── E1 live policy promotion — boj-server#208 (landed)
     ├── §1.5 operator pre-check smoke — boj-server#210 (landed)
     ├── §1.5 verb-canary expansion — THIS PR (in review)
     ├── E1 .ctp signing — owner follow-up
     ├── E2 staging cut-over — owner follow-up
     ├── E3 telemetry verification — owner follow-up
     ├── E4 production rollout — owner follow-up
     └── §6.4 Trustfile flip + §6.5 joint-close — owner-only
```

Refs hyperpolymath/standards#91
Refs hyperpolymath/standards#100

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---
_Generated by [Claude
Code](https://claude.ai/code/session_01NgeisSDPZ7NJSjkhU95qYS)_

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant